home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 424_01 / ed_157 / libc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-10  |  20.0 KB  |  969 lines

  1. /*
  2.  * Copyright (C) 1992 by Rush Record (rhr@clio.rice.edu)
  3.  * 
  4.  * This file is part of ED.
  5.  * 
  6.  * ED is free software; you can redistribute it and/or modify it under the terms
  7.  * of the GNU General Public License as published by the Free Software Foundation.
  8.  * 
  9.  * ED is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  10.  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  11.  * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  12.  * 
  13.  * You should have received a copy of the GNU General Public License along with ED
  14.  * (see the file COPYING).  If not, write to the Free Software Foundation, 675
  15.  * Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17. #include "opsys.h"
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <math.h>
  22. #ifdef VMS
  23. #include <stdarg.h>
  24. #else
  25. #include <varargs.h>
  26. #endif
  27. #include "ctyp_dec.h"
  28.  
  29. static Uchar list[256];    /* for [...] expressions */
  30.  
  31. /******************************************************************************\
  32. |Routine: tentothe
  33. |Callby: libc
  34. |Purpose: Returns powers of ten.
  35. |Arguments:
  36. |    i is the power to raise ten to.
  37. \******************************************************************************/
  38. double tentothe(i)
  39. Int i;
  40. {
  41.     static double powers[] =
  42.     {
  43.         1e0,1e1,1e2,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13,1e14,1e15,
  44.         1e16,1e17,1e18,1e19,1e20,1e21,1e22,1e23,1e24,1e25,1e26,1e27,1e28,1e29,1e30,1e31,
  45.         1e32,1e33,1e34,1e35,1e36,1e37,1e38
  46.     };
  47.     Int j;
  48.     
  49.     j = (sizeof(powers) / sizeof(double)) - 1;
  50.     if(i > j)
  51.         i = j;
  52.     else if(i < -j)
  53.         i = -j;
  54.     return((i >= 0)? powers[i] : (1.0 / powers[-i]));
  55. }
  56.  
  57. /******************************************************************************\
  58. |Routine: my_sscanf
  59. |Callby: calculate cfg command help_get_kw init_term parse_fnm restore_par set_param store_param wincom
  60. |Purpose: Does what sscanf() does.
  61. |Arguments:
  62. |    inbuf is a string containing formatted data.
  63. |    fmt is the format string.
  64. \******************************************************************************/
  65. #ifdef VMS
  66. Int my_sscanf(inbuf,fmt)
  67. Char *inbuf,*fmt;
  68. #else
  69. Int my_sscanf(va_alist)
  70. va_dcl
  71. #endif
  72. {
  73.     va_list ap;
  74. #ifndef VMS
  75.     Char *inbuf,*fmt;
  76. #endif
  77.     Uchar *b,*f,*save;
  78.     unsigned long ival;
  79.     double dval;
  80.     Int digcount,i,j,c;
  81.     Int suppress,width,size,sign,unsg,not,cnvcount,decimals,pastpoint,esign,edigcount,signpresent,pointpresent;
  82.     Char *cp;
  83.     short *sp;
  84.     Int *ip;
  85.     long *lp;
  86.     float *fp;
  87.     double *dp;
  88.     void **vp;
  89.  
  90. #ifdef VMS
  91.     va_start(ap,fmt);
  92. #else
  93.     va_start(ap);
  94.     inbuf = va_arg(ap,Char *);
  95.     fmt = va_arg(ap,Char *);
  96. #endif
  97.  
  98.     f = (Uchar *)fmt;
  99.     b = (Uchar *)inbuf;
  100.     cnvcount = 0;
  101.     while((c = *f++))
  102.         switch(c)
  103.         {
  104.             case '%':
  105.                 if(*f != '[' && *f != 'n' && *f != 'c' && *f != '%')
  106.                     while(isspace(*b))
  107.                         b++;
  108.                 suppress = 0;    /* suppression of assignment */
  109.                 width = 0;    /* enforced field maximum width (zero if no limit) */
  110.                 size = 0;    /* -1 = short, 0 = int, +1 = long, (or -1 or 0 = float, 1 = double, 2 = long double) */
  111.                 sign = 1;    /* sign of result */
  112.                 unsg = 0;    /* require unsigned int value */
  113. redo:
  114.                 switch((c = *f++))
  115.                 {
  116.                     case '*':
  117.                         suppress = 1;
  118.                         goto redo;
  119.                     case '0':
  120.                     case '1':
  121.                     case '2':
  122.                     case '3':
  123.                     case '4':
  124.                     case '5':
  125.                     case '6':
  126.                     case '7':
  127.                     case '8':
  128.                     case '9':
  129.                         width = c - '0';
  130.                         while(isdigit((c = *f++)))
  131.                             width = 10 * width + c - '0';
  132.                         f--;
  133.                         goto redo;
  134.                     case 'h':
  135.                         size = -1;
  136.                         goto redo;
  137.                     case 'l':
  138.                         size = 1;
  139.                         goto redo;
  140.                     case 'L':
  141.                         size = 2;
  142.                         goto redo;
  143.                     case 'd':
  144. dec:
  145.                         ival = 0;
  146.                         digcount = 0;
  147.                         if(*b == '-')
  148.                         {
  149.                             if(unsg)
  150.                                 return(0);
  151.                             sign = -1;
  152.                             b++;
  153.                         }
  154.                         else if(*b == '+')
  155.                             b++;
  156.                         while(isdigit((i = *b++)))
  157.                         {
  158.                             ival = 10 * ival + i - '0';
  159.                             ++digcount;
  160.                             if(width)
  161.                                 if(digcount >= width)
  162.                                 {
  163.                                     b++;    /* because of the b-- below */
  164.                                     break;
  165.                                 }
  166.                         }
  167. integer:
  168.                         if(!digcount)
  169.                             return(0);
  170.                         b--;
  171.                         if(!suppress)
  172.                         {
  173.                             if(sign < 0)
  174.                                 ival = -ival;
  175.                             switch(size)
  176.                             {
  177.                                 case -1:
  178.                                     sp = va_arg(ap,short *);
  179.                                     *sp = ival;
  180.                                     break;
  181.                                 case 0:
  182.                                     ip = va_arg(ap,Int *);
  183.                                     *ip = ival;
  184.                                     break;
  185.                                 case 1:
  186.                                 case 2:
  187.                                     lp = va_arg(ap,long *);
  188.                                     *lp = ival;
  189.                                     break;
  190.                             }
  191.                             cnvcount++;
  192.                         }
  193.                         break;
  194.                     case 'i':
  195.                         if((i = *b++) == '0')
  196.                             if(*b == 'x' || *b == 'X')
  197.                             {
  198.                                 b++;
  199.                                 goto hex;
  200.                             }
  201.                             else
  202.                                 goto oct;
  203.                         b--;
  204.                         goto dec;
  205.                     case 'o':
  206. oct:
  207.                         ival = 0;
  208.                         digcount = 0;
  209.                         while(isdigit((i = *b++)))
  210.                         {
  211.                             if(i == '8' || i == '9')
  212.                                 return(0);
  213.                             ival = (ival << 3) + i - '0';
  214.                             digcount++;
  215.                             if(width)
  216.                                 if(digcount >= width)
  217.                                 {
  218.                                     b++;    /* because of the b-- below integer: */
  219.                                     break;
  220.                                 }
  221.                         }
  222.                         goto integer;
  223.                     case 'u':
  224.                         unsg = 1;
  225.                         goto dec;
  226.                     case 'x':
  227. hex:
  228.                         ival = 0;
  229.                         digcount = 0;
  230.                         while(isxdigit((i = *b++)))
  231.                         {
  232.                             ival <<= 4;
  233.                             if(i >= '0' && i <= '9')
  234.                                 ival += i - '0';
  235.                             else if(i >= 'A' && i <= 'F')
  236.                                 ival += i - 'A' + 10;
  237.                             else if(i >= 'a' && i <= 'f')
  238.                                 ival += i - 'a' + 10;
  239.                             digcount++;
  240.                             if(width)
  241.                                 if(digcount >= width)
  242.                                 {
  243.                                     b++;    /* because of the b-- below integer: */
  244.                                     break;
  245.                                 }
  246.                         }
  247.                         goto integer;
  248.                     case 'c':
  249.                         cp = va_arg(ap,Char *);
  250.                         *cp = *b++;
  251.                         cnvcount++;
  252.                         break;
  253.                     case 's':
  254.                         cp = va_arg(ap,Char *);
  255.                         while(!isspace((i = *b++)))
  256.                             *cp++ = i;
  257.                         b--;
  258.                         *cp = '\0';
  259.                         cnvcount++;
  260.                         break;
  261.                     case 'e':
  262.                     case 'f':
  263.                     case 'g':
  264.                         ival = 0;    /* this is the exponent */
  265.                         dval = 0.0;
  266.                         digcount = 0;
  267.                         signpresent = 0;
  268.                         pointpresent = 0;
  269.                         if(*b == '-')
  270.                         {
  271.                             sign = -1;
  272.                             b++;
  273.                             digcount++;
  274.                             signpresent = 1;
  275.                         }
  276.                         else if(*b == '+')
  277.                         {
  278.                             b++;
  279.                             digcount++;
  280.                             signpresent = 1;
  281.                         }
  282.                         decimals = 0;
  283.                         pastpoint = 0;
  284. floatdigits:
  285.                         while(isdigit((i = *b++)))
  286.                         {
  287.                             if(pastpoint)
  288.                                 decimals++;
  289.                             dval = 10.0 * dval + (double)(i - '0');
  290.                             ++digcount;
  291.                             if(width)
  292.                                 if(digcount >= width)
  293.                                 {
  294.                                     b++;    /* because of the b-- below */
  295.                                     goto floating;
  296.                                 }
  297.                         }
  298.                         if(i == '.')
  299.                         {
  300.                             pointpresent = 1;
  301.                             digcount++;
  302.                             if(pastpoint)
  303.                                 goto floating;
  304.                             pastpoint = 1;
  305.                             if(width)
  306.                                 if(digcount >= width)
  307.                                 {
  308.                                     b++;    /* because of the b-- below */
  309.                                     goto floating;
  310.                                 }
  311.                             goto floatdigits;
  312.                         }
  313.                         if(!(digcount - signpresent - pointpresent))
  314.                             return(0);
  315.                         if(i == 'e' || i == 'E')
  316.                         {
  317.                             edigcount = 0;
  318.                             esign = 1;
  319.                             if(*b == '-')
  320.                             {
  321.                                 esign = -1;
  322.                                 b++;
  323.                             }
  324.                             else if(*b == '+')
  325.                                 b++;
  326.                             while(isdigit((i = *b++)))
  327.                             {
  328.                                 ival = 10 * ival + i - '0';
  329.                                 edigcount++;
  330.                             }
  331.                             if(!edigcount)    /* assume the e or E is part of a string */
  332.                             {
  333.                                 b--;
  334.                                 goto floating;
  335.                             }
  336.                         }
  337. floating:
  338.                         b--;    /* back up to char that terminated number */
  339.                         if(!suppress)
  340.                         {
  341.                             if(pastpoint)
  342.                                 dval /= tentothe(decimals);
  343.                             if(esign < 0)
  344.                                 ival = -ival;
  345.                             if(ival)
  346.                                 dval *= tentothe(ival);
  347.                             if(sign < 0)
  348.                                 dval = -dval;
  349.                             switch(size)
  350.                             {
  351.                                 case -1:
  352.                                 case 0:
  353.                                     fp = va_arg(ap,float *);
  354.                                     *fp = (float)dval;
  355.                                     break;
  356.                                 case 1:
  357.                                 case 2:
  358.                                     dp = va_arg(ap,double *);
  359.                                     *dp = (double)dval;
  360.                                     break;
  361.                             }
  362.                             cnvcount++;
  363.                         }
  364.                         break;
  365.                     case 'p':
  366.                         if(*b++ != '0')
  367.                             return(0);
  368.                         i = *b++;
  369.                         if(i != 'x' && i != 'X')
  370.                             return(0);
  371.                         ival = 0;
  372.                         for(j = (sizeof(void *) << 1);j--;)
  373.                         {
  374.                             if(!isxdigit((i = *b++)))
  375.                                 return(0);
  376.                             ival <<= 4;
  377.                             if(i >= '0' && i <= '9')
  378.                                 ival += i - '0';
  379.                             else if(i >= 'A' && i <= 'F')
  380.                                 ival += i - 'A' + 10;
  381.                             else if(i >= 'a' && i <= 'f')
  382.                                 ival += i - 'a' + 10;
  383.                         }
  384.                         vp = va_arg(ap,void **);    /* this assumes that char * and void * are the same size */
  385.                         *vp = (void *)ival;
  386.                         cnvcount++;
  387.                         break;
  388.                     case 'n':
  389.                         if(suppress || width || size)
  390.                             return(0);
  391.                         ip = va_arg(ap,Int *);
  392.                         *ip = b - (Uchar *)inbuf;
  393.                         break;
  394.                     case '[':
  395.                         save = f;
  396.                         not = 0;
  397.                         if(*f == '^')
  398.                         {
  399.                             not = 1;
  400.                             f++;
  401.                         }
  402.                         if(*f == ']')
  403.                         {
  404.                             list[']'] = 1;
  405.                             f++;
  406.                         }
  407.                         while((i = *f++) != ']')
  408.                             list[i] = 1;
  409.                         cp = va_arg(ap,Char *);
  410.                         if(not)
  411.                         {
  412.                             while(list[(int)*b++]);    /* find a non-member of the set */
  413.                             while(!list[(i = *b++)])
  414.                                 *cp++ = i;
  415.                         }
  416.                         else
  417.                         {
  418.                             while(!list[*b++]);    /* find a member of the set */
  419.                             while(list[(i = *b++)])
  420.                                 *cp++ = i;
  421.                         }
  422.                         *cp = '\0';
  423.                         cnvcount++;
  424.                         b--;
  425.                         f = save;    /* restore list[] to all zeroes (faster than memset(list,0,256)) */
  426.                         if(*f == '^')
  427.                             f++;
  428.                         if(*f == ']')
  429.                         {
  430.                             list[']'] = 0;
  431.                             f++;
  432.                         }
  433.                         while((i = *f++) != ']')
  434.                             list[i] = 0;
  435.                         break;
  436.                     case '%':
  437.                         if(*b++ != '%')
  438.                             return(0);
  439.                         break;
  440.                     default:
  441.                         return(0);
  442.                 }
  443.                 break;
  444.             default:
  445.                 if(c != ' ' && c != '\t')
  446.                     if(*b++ != c)
  447.                         return(0);
  448.         }
  449.     return(cnvcount);
  450. }
  451.  
  452. static FILE *my_fp;
  453. static Uchar ungetbuf[8];
  454. static Uchar *ungetp;
  455. static Int getcount;
  456.  
  457. /******************************************************************************\
  458. |Routine: my_fgetc
  459. |Callby: libc
  460. |Purpose: Does what fgetc does.
  461. |Arguments:
  462. |    fp is the file pointer.
  463. \******************************************************************************/
  464. Int my_fgetc()
  465. {
  466.     getcount++;
  467.     if(ungetp != ungetbuf)
  468.         return(*--ungetp);
  469.     return(fgetc(my_fp));
  470. }
  471.  
  472. /******************************************************************************\
  473. |Routine: my_ungetc
  474. |Callby: libc
  475. |Purpose: Does what ungetc does.
  476. |Arguments:
  477. |    c is the ungot character.
  478. \******************************************************************************/
  479. void my_ungetc(c)
  480. Int c;
  481. {
  482.     getcount--;
  483.     *ungetp++ = c;
  484. }
  485.  
  486. /******************************************************************************\
  487. |Routine: my_fscanf
  488. |Callby: help_get_kw init_term journal restore_par store_param
  489. |Purpose: Does what fscanf does.
  490. |Arguments:
  491. |    pfp is the file pointer.
  492. |    fmt is the format string.
  493. \******************************************************************************/
  494. #ifdef VMS
  495. Int my_fscanf(pfp,fmt)
  496. FILE *pfp;
  497. Char *fmt;
  498. #else
  499. Int my_fscanf(va_alist)
  500. va_dcl
  501. #endif
  502. {
  503.     va_list ap;
  504. #ifndef VMS
  505.     FILE *pfp;
  506.     Char *fmt;
  507. #endif
  508.     Uchar *f,*save;
  509.     unsigned long ival;
  510.     double dval;
  511.     Int digcount,i,j,c;
  512.     Int suppress,width,size,sign,unsg,not,cnvcount,decimals,pastpoint,esign,edigcount,signpresent,pointpresent,save_e;
  513.     Char *cp;
  514.     short *sp;
  515.     Int *ip;
  516.     long *lp;
  517.     float *fp;
  518.     double *dp;
  519.     void **vp;
  520.  
  521. #ifdef VMS
  522.     va_start(ap,fmt);
  523. #else
  524.     va_start(ap);
  525.     pfp = va_arg(ap,FILE *);
  526.     fmt = va_arg(ap,Char *);
  527. #endif
  528.     getcount = 0;
  529.     my_fp = pfp;
  530.     ungetp = ungetbuf;
  531.     f = (Uchar *)fmt;
  532.     cnvcount = 0;
  533.     while((c = *f++))
  534.         switch(c)
  535.         {
  536.             case '%':
  537.                 if(*f != '[' && *f != 'n' && *f != 'c' && *f != '%')
  538.                 {
  539.                     while(1)
  540.                     {
  541.                         if((i = my_fgetc()) == EOF)
  542.                             return(EOF);
  543.                         if(!isspace(i))
  544.                             break;
  545.                     }
  546.                     my_ungetc(i);
  547.                 }
  548.                 suppress = 0;    /* suppression of assignment */
  549.                 width = 0;    /* enforced field maximum width (zero if no limit) */
  550.                 size = 0;    /* -1 = short, 0 = int, +1 = long, (or -1 or 0 = float, 1 = double, 2 = long double) */
  551.                 sign = 1;    /* sign of result */
  552.                 unsg = 0;    /* require unsigned int value */
  553. redo:
  554.                 switch((c = *f++))
  555.                 {
  556.                     case '*':
  557.                         suppress = 1;
  558.                         goto redo;
  559.                     case '0':
  560.                     case '1':
  561.                     case '2':
  562.                     case '3':
  563.                     case '4':
  564.                     case '5':
  565.                     case '6':
  566.                     case '7':
  567.                     case '8':
  568.                     case '9':
  569.                         width = c - '0';
  570.                         while(isdigit((c = *f++)))
  571.                             width = 10 * width + c - '0';
  572.                         f--;
  573.                         goto redo;
  574.                     case 'h':
  575.                         size = -1;
  576.                         goto redo;
  577.                     case 'l':
  578.                         size = 1;
  579.                         goto redo;
  580.                     case 'L':
  581.                         size = 2;
  582.                         goto redo;
  583.                     case 'd':
  584. dec:
  585.                         ival = 0;
  586.                         digcount = 0;
  587.                         if((i = my_fgetc()) == EOF)
  588.                             return(EOF);
  589.                         else if(i == '-')
  590.                         {
  591.                             if(unsg)
  592.                                 return(0);
  593.                             sign = -1;
  594.                         }
  595.                         else if(i != '+')
  596.                             my_ungetc(i);
  597.                         while(1)
  598.                         {
  599.                             if((i = my_fgetc()) == EOF)
  600.                                 return(EOF);
  601.                             if(!isdigit(i))
  602.                                 break;
  603.                             ival = 10 * ival + i - '0';
  604.                             ++digcount;
  605.                             if(width)
  606.                                 if(digcount >= width)
  607.                                 {
  608.                                     if((i = my_fgetc()) == EOF)    /* because of the my_ungetc() below */
  609.                                         return(EOF);
  610.                                     break;
  611.                                 }
  612.                         }
  613. integer:
  614.                         if(!digcount)
  615.                             return(0);
  616.                         my_ungetc(i);
  617.                         if(!suppress)
  618.                         {
  619.                             if(sign < 0)
  620.                                 ival = -ival;
  621.                             switch(size)
  622.                             {
  623.                                 case -1:
  624.                                     sp = va_arg(ap,short *);
  625.                                     *sp = ival;
  626.                                     break;
  627.                                 case 0:
  628.                                     ip = va_arg(ap,Int *);
  629.                                     *ip = ival;
  630.                                     break;
  631.                                 case 1:
  632.                                 case 2:
  633.                                     lp = va_arg(ap,long *);
  634.                                     *lp = ival;
  635.                                     break;
  636.                             }
  637.                             cnvcount++;
  638.                         }
  639.                         break;
  640.                     case 'i':
  641.                         if((i = my_fgetc()) == EOF)
  642.                             return(EOF);
  643.                         else if(i == '0')
  644.                         {
  645.                             if((i = my_fgetc()) == EOF)
  646.                                 return(EOF);
  647.                             if(i == 'x' || i == 'X')
  648.                                 goto hex;
  649.                             else
  650.                             {
  651.                                 my_ungetc(i);
  652.                                 goto oct;
  653.                             }
  654.                         }
  655.                         my_ungetc(i);
  656.                         goto dec;
  657.                     case 'o':
  658. oct:
  659.                         ival = 0;
  660.                         digcount = 0;
  661.                         while(1)
  662.                         {
  663.                             if((i = my_fgetc()) == EOF)
  664.                                 return(EOF);
  665.                             if(!isdigit(i))
  666.                                 break;
  667.                             if(i == '8' || i == '9')
  668.                                 return(0);
  669.                             ival = (ival << 3) + i - '0';
  670.                             digcount++;
  671.                             if(width)
  672.                                 if(digcount >= width)
  673.                                 {
  674.                                     if((i = my_fgetc()) == EOF)    /* because of the my_ungetc() below integer: */
  675.                                         return(EOF);
  676.                                     break;
  677.                                 }
  678.                         }
  679.                         goto integer;
  680.                     case 'u':
  681.                         unsg = 1;
  682.                         goto dec;
  683.                     case 'x':
  684. hex:
  685.                         ival = 0;
  686.                         digcount = 0;
  687.                         while(1)
  688.                         {
  689.                             if((i = my_fgetc()) == EOF)
  690.                                 return(EOF);
  691.                             if(!isxdigit(i))
  692.                                 break;
  693.                             ival <<= 4;
  694.                             if(i >= '0' && i <= '9')
  695.                                 ival += i - '0';
  696.                             else if(i >= 'A' && i <= 'F')
  697.                                 ival += i - 'A' + 10;
  698.                             else if(i >= 'a' && i <= 'f')
  699.                                 ival += i - 'a' + 10;
  700.                             digcount++;
  701.                             if(width)
  702.                                 if(digcount >= width)
  703.                                 {
  704.                                     if((i = my_fgetc()) == EOF)    /* because of the my_ungetc() below integer: */
  705.                                         return(EOF);
  706.                                     break;
  707.                                 }
  708.                         }
  709.                         goto integer;
  710.                     case 'c':
  711.                         cp = va_arg(ap,Char *);
  712.                         if((i = my_fgetc()) == EOF)
  713.                             return(EOF);
  714.                         *cp = i;
  715.                         cnvcount++;
  716.                         break;
  717.                     case 's':
  718.                         cp = va_arg(ap,Char *);
  719.                         while(1)
  720.                         {
  721.                             if((i = my_fgetc()) == EOF)
  722.                                 return(EOF);
  723.                             if(isspace(i))
  724.                                 break;
  725.                             *cp++ = i;
  726.                         }
  727.                         *cp = '\0';
  728.                         my_ungetc(i);
  729.                         cnvcount++;
  730.                         break;
  731.                     case 'e':
  732.                     case 'f':
  733.                     case 'g':
  734.                         ival = 0;    /* this is the exponent */
  735.                         dval = 0.0;
  736.                         digcount = 0;
  737.                         signpresent = 0;
  738.                         pointpresent = 0;
  739.                         if((i = my_fgetc()) == EOF)
  740.                             return(EOF);
  741.                         else if(i == '-')
  742.                         {
  743.                             sign = -1;
  744.                             digcount++;
  745.                             signpresent = 1;
  746.                         }
  747.                         else if(i == '+')
  748.                         {
  749.                             digcount++;
  750.                             signpresent = 1;
  751.                         }
  752.                         else
  753.                             my_ungetc(i);
  754.                         decimals = 0;
  755.                         pastpoint = 0;
  756. floatdigits:
  757.                         while(1)
  758.                         {
  759.                             if((i = my_fgetc()) == EOF)
  760.                                 return(EOF);
  761.                             if(!isdigit(i))
  762.                                 break;
  763.                             if(pastpoint)
  764.                                 decimals++;
  765.                             dval = 10.0 * dval + (double)(i - '0');
  766.                             ++digcount;
  767.                             if(width)
  768.                                 if(digcount >= width)
  769.                                 {
  770.                                     if((i = my_fgetc()) == EOF)    /* because of the my_ungetc() below */
  771.                                         return(EOF);
  772.                                     goto floating;
  773.                                 }
  774.                         }
  775.                         if(i == '.')
  776.                         {
  777.                             pointpresent = 1;
  778.                             digcount++;
  779.                             if(pastpoint)
  780.                                 goto floating;
  781.                             pastpoint = 1;
  782.                             if(width)
  783.                                 if(digcount >= width)
  784.                                 {
  785.                                     if((i = my_fgetc()) == EOF)    /* because of the my_ungetc() below */
  786.                                         return(EOF);
  787.                                     goto floating;
  788.                                 }
  789.                             goto floatdigits;
  790.                         }
  791.                         if(!(digcount - signpresent - pointpresent))
  792.                             return(0);
  793.                         if(i == 'e' || i == 'E')
  794.                         {
  795.                             save_e = i;
  796.                             edigcount = 0;
  797.                             esign = 1;
  798.                             if((i = my_fgetc()) == EOF)
  799.                                 return(EOF);
  800.                             else if(i == '-')
  801.                                 esign = -1;
  802.                             else if(i != '+')
  803.                                 my_ungetc(i);
  804.                             while(1)
  805.                             {
  806.                                 if((i = my_fgetc()) == EOF)
  807.                                     return(EOF);
  808.                                 if(!isdigit(i))
  809.                                     break;
  810.                                 ival = 10 * ival + i - '0';
  811.                                 edigcount++;
  812.                             }
  813.                             if(!edigcount)    /* assume the e or E is part of a string */
  814.                             {
  815.                                 my_ungetc(save_e);
  816.                                 goto floating;
  817.                             }
  818.                         }
  819. floating:
  820.                         my_ungetc(i);    /* back up to char that terminated number */
  821.                         if(!suppress)
  822.                         {
  823.                             if(pastpoint)
  824.                                 dval /= tentothe(decimals);
  825.                             if(esign < 0)
  826.                                 ival = -ival;
  827.                             if(ival)
  828.                                 dval *= tentothe(ival);
  829.                             if(sign < 0)
  830.                                 dval = -dval;
  831.                             switch(size)
  832.                             {
  833.                                 case -1:
  834.                                 case 0:
  835.                                     fp = va_arg(ap,float *);
  836.                                     *fp = (float)dval;
  837.                                     break;
  838.                                 case 1:
  839.                                 case 2:
  840.                                     dp = va_arg(ap,double *);
  841.                                     *dp = (double)dval;
  842.                                     break;
  843.                             }
  844.                             cnvcount++;
  845.                         }
  846.                         break;
  847.                     case 'p':
  848.                         if((i = my_fgetc()) == EOF)
  849.                             return(EOF);
  850.                         if(i != '0')
  851.                             return(0);
  852.                         if((i = my_fgetc()) == EOF)
  853.                             return(EOF);
  854.                         if(i != 'x' && i != 'X')
  855.                             return(0);
  856.                         ival = 0;
  857.                         for(j = (sizeof(void *) << 1);j--;)
  858.                         {
  859.                             if((i = my_fgetc()) == EOF)
  860.                                 return(EOF);
  861.                             if(!isxdigit((i)))
  862.                                 return(0);
  863.                             ival <<= 4;
  864.                             if(i >= '0' && i <= '9')
  865.                                 ival += i - '0';
  866.                             else if(i >= 'A' && i <= 'F')
  867.                                 ival += i - 'A' + 10;
  868.                             else if(i >= 'a' && i <= 'f')
  869.                                 ival += i - 'a' + 10;
  870.                         }
  871.                         vp = va_arg(ap,void **);    /* this assumes that char * and void * are the same size */
  872.                         *vp = (void *)ival;
  873.                         cnvcount++;
  874.                         break;
  875.                     case 'n':
  876.                         if(suppress || width || size)
  877.                             return(0);
  878.                         ip = va_arg(ap,Int *);
  879.                         *ip = getcount;
  880.                         break;
  881.                     case '[':
  882.                         save = f;
  883.                         not = 0;
  884.                         if(*f == '^')
  885.                         {
  886.                             not = 1;
  887.                             f++;
  888.                         }
  889.                         if(*f == ']')
  890.                         {
  891.                             list[']'] = 1;
  892.                             f++;
  893.                         }
  894.                         while((i = *f++) != ']')
  895.                             list[i] = 1;
  896.                         cp = va_arg(ap,Char *);
  897.                         if(not)
  898.                         {
  899.                             while(1)
  900.                             {
  901.                                 if((i = my_fgetc()) == EOF)
  902.                                     return(EOF);
  903.                                 if(!list[i])    /* find a non-member of the set */
  904.                                     break;
  905.                             }
  906.                             while(1)
  907.                             {
  908.                                 if((i = my_fgetc()) == EOF)
  909.                                     return(EOF);
  910.                                 if(list[i])
  911.                                     break;
  912.                                 *cp++ = i;
  913.                             }
  914.                         }
  915.                         else
  916.                         {
  917.                             while(1)
  918.                             {
  919.                                 if((i = my_fgetc()) == EOF)
  920.                                     return(EOF);
  921.                                 if(list[i])    /* find a member of the set */
  922.                                     break;
  923.                             }
  924.                             while(1)
  925.                             {
  926.                                 if((i = my_fgetc()) == EOF)
  927.                                     return(EOF);
  928.                                 if(!list[i])
  929.                                     break;
  930.                                 *cp++ = i;
  931.                             }
  932.                         }
  933.                         *cp = '\0';
  934.                         cnvcount++;
  935.                         my_ungetc(i);
  936.                         f = save;    /* restore list[] to all zeroes (faster than memset(list,0,256)) */
  937.                         if(*f == '^')
  938.                             f++;
  939.                         if(*f == ']')
  940.                         {
  941.                             list[']'] = 0;
  942.                             f++;
  943.                         }
  944.                         while((i = *f++) != ']')
  945.                             list[i] = 0;
  946.                         break;
  947.                     case '%':
  948.                         if((i = my_fgetc()) == EOF)
  949.                             return(EOF);
  950.                         if(i != '%')
  951.                             return(0);
  952.                         break;
  953.                     default:
  954.                         return(0);
  955.                 }
  956.                 break;
  957.             default:
  958.                 if(c != ' ' && c != '\t')
  959.                 {
  960.                     if((i = my_fgetc()) == EOF)
  961.                         return(EOF);
  962.                     if(i != c)
  963.                         return(0);
  964.                 }
  965.         }
  966.     return(cnvcount);
  967. }
  968.  
  969.